home *** CD-ROM | disk | FTP | other *** search
/ MacGames Sampler / PHT MacGames Bundle.iso / MacSource Folder / Samples from the CD / Editors / emacs / Emacs-1.14b1-sources / sources / misc-src / alloca.c next >
Encoding:
C/C++ Source or Header  |  1994-05-25  |  1.7 KB  |  68 lines  |  [TEXT/EMAC]

  1. /*
  2.  * Copyright (C) 1993, 1994 Marc Parmet.
  3.  * This file is part of the Macintosh port of GNU Emacs.
  4.  *
  5.  * GNU Emacs is distributed in the hope that it will be useful,
  6.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  8.  * GNU General Public License for more details.
  9.  */
  10.  
  11. /*
  12.     This implementation of alloca works by copying the register
  13.     variable storage when allocating any space.  If all register
  14.     variables are in use, and, more data is already pushed onto the
  15.     stack at the time of the call to alloca, then alloca will
  16.     fail to correctly fix up the stack, resulting in an error
  17.     far down the line.
  18.  
  19.     For example, if all register variables are in use, and this call is made:
  20.         p = f(a,alloca(n),b);
  21.     alloca will fail if b is pushed in preparation for the call to f before
  22.     the call to alloca.
  23.     
  24.     This never happens in Emacs, but one day someone will hack code that uses alloca,
  25.     and then wonder why it's crashing.
  26. */
  27.  
  28. #include <setjmp.h>
  29.  
  30. // This must be at least as big as the space needed for all register variables
  31. #define REGSPACE sizeof(jmp_buf)
  32.  
  33. #if defined(__MWERKS__)
  34. asm
  35. #endif
  36. char *
  37. alloca(/* long n */)
  38. {
  39. #if defined(THINK_C)
  40.     asm {
  41. #endif
  42.         // Remove parameters
  43.         move.l    (a7)+,a0
  44.         move.l    (a7)+,d0
  45.         
  46.         // Size must be even, so round up.
  47.         addq.l    #1,d0
  48.         bclr    #0,d0
  49.         
  50.         // Save bottom of old register storage
  51.         lea        REGSPACE(a7),a1
  52.  
  53.         // Take desired space
  54.         sub.l    d0,a7
  55.         move.l    a7,d0
  56.  
  57.         // Copy register storage of caller
  58.         moveq.l    #(REGSPACE/4 - 1),d1
  59. top:    move.l    -(a1),-(a7)
  60.         dbf        d1,@top
  61.  
  62.         subq.l    #4,a7 // For when the caller tries to pop the argument off the stack
  63.         jmp        (a0)
  64. #if defined(THINK_C)
  65.     }
  66. #endif
  67. }
  68.